home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Delphi Magazine Collection 2001
/
Delphi Magazine Collection 20001 (2001).iso
/
DISKS
/
Issue34
/
alfresco
/
trie.pas
< prev
next >
Wrap
Pascal/Delphi Source File
|
1998-04-21
|
4KB
|
134 lines
{*********************************************************}
{* Trie *}
{* Copyright (c) Julian M Bucknall 1998 *}
{* All rights reserved. *}
{*********************************************************}
{* A simple trie class *}
{*********************************************************}
{Note: this unit is released as freeware. In other words, you are free
to use this unit in your own applications, however I retain all
copyright to the code. JMB}
{$IFDEF VER80}
!! Error
This unit uses long strings only. In other words, you must be using
Delphi 2 or later.
{$ENDIF}
unit Trie;
interface
type
PTrieNode = ^TTrieNode;
TTrieNode = array [#0..#255] of PTrieNode;
type
TTrie = class
protected {private}
FRoot : PTrieNode;
FNodeCount : integer;
protected
procedure KillNodes(aRoot : PTrieNode);
function FindPrim(const S : string;
var aData : pointer;
var aNode : PTrieNode;
var aChPos : integer) : boolean;
public
constructor Create;
destructor Destroy; override;
procedure AddObject(const S : string; aData : pointer);
function FindString(const S : string; var aData : pointer) : boolean;
property NodeCount : integer read FNodeCount;
end;
implementation
{===TTrie============================================================}
constructor TTrie.Create;
begin
{allocate the root node}
New(FRoot);
FNodeCount := 1;
FillChar(FRoot^, sizeof(TTrieNode), 0);
end;
{--------}
destructor TTrie.Destroy;
begin
{destroy all nodes recursively}
KillNodes(FRoot);
end;
{--------}
procedure TTrie.AddObject(const S : string; aData : pointer);
var
DummyData : pointer;
Node : PTrieNode;
NewNode : PTrieNode;
ChPos : integer;
i : integer;
begin
{if the string already exists, ignore the call}
if FindPrim(S, DummyData, Node, ChPos) then
Exit;
{now create a node for each remaining character in S}
for i := ChPos to length(S) do begin
New(NewNode);
inc(FNodeCount);
FillChar(NewNode^, sizeof(TTrieNode), 0);
Node^[S[i]] := NewNode;
Node := NewNode;
end;
{patch the terminator link to the given data}
Node^[#0] := aData;
end;
{--------}
function TTrie.FindPrim(const S : string;
var aData : pointer;
var aNode : PTrieNode;
var aChPos : integer) : boolean;
var
Node : PTrieNode;
i : integer;
begin
Node := FRoot;
for i := 1 to succ(length(S)) do begin
aNode := Node;
Node := Node^[S[i]];
if (Node = nil) then begin
Result := false;
aData := nil;
aChPos := i;
Exit;
end;
end;
Result := true;
aData := Node;
end;
{--------}
function TTrie.FindString(const S : string; var aData : pointer) : boolean;
var
DummyNode : PTrieNode;
DummyChPos: integer;
begin
Result := FindPrim(S, aData, DummyNode, DummyChPos);
end;
{--------}
procedure TTrie.KillNodes(aRoot : PTrieNode);
var
Ch : char;
begin
if (aRoot <> nil) then begin
{kill all children, recursively; ignore #0}
for Ch := #1 to #255 do
KillNodes(aRoot^[Ch]);
{kill root node}
Dispose(aRoot);
end;
end;
{====================================================================}
end.